package njust.csc.aecore.utils

import java.nio.file.Path
import kotlin.io.path.*

/**
 * @Author ZhouHang
 * @Date 24/5/29 周三
 */
object PathUtils {
    private val HOME = Path(System.getenv("APKEXPLORER_HOME"))
    val INPUT: Path = HOME.resolve("input")
    val OUTPUT: Path = HOME.resolve("output")
    private val ANDROID_HOME = Path(System.getenv("ANDROID_HOME"))
    val ANDROID_JAR: Path = ANDROID_HOME.resolve("platforms")

    /**
     * 将相对路径连接到 INPUT 上
     * @param relativePath 相对路径
     * */
    fun inputResolve(relativePath: String): Path {
        return INPUT.resolve(relativePath)
    }

    /**
     * 获得 APK 提取信息的输出路径
     * */
    fun getBaseInfoPath(relativePath: String, needParent: Boolean = true): Path {
        if (needParent) {
            val parentDir = OUTPUT.resolve(relativePath).parent
            parentDir.createDirectories()  // 确保目录存在
            return parentDir.resolve("baseInfo.jsonl")
        } else {
            val parentDir = OUTPUT.resolve(relativePath)
            parentDir.createDirectories()  // 确保目录存在
            return parentDir.resolve("baseInfo.jsonl")
        }
    }

    /**
     * 获取 APK 完整信息路径
     * */
    fun getFullInfoPath(relativePath: String): Path {
        val parentDir = OUTPUT.resolve(relativePath).parent
        parentDir.createDirectories()  // 确保目录存在
        return parentDir.resolve("fullInfo.jsonl")
    }

    /**
     * 获取 jadx 反汇编后的文件保存路径
     * */
    fun getReversePath(relativePath: String): Path {
        val apkName = Path(relativePath).nameWithoutExtension
        val parentDir = OUTPUT.resolve(relativePath).parent
        val targetDir = parentDir.resolve(apkName).resolve("jadx")
        targetDir.createDirectories()
        return targetDir
    }

    /**
     * 删除文件夹
     * */
    @OptIn(ExperimentalPathApi::class)
    fun deleteDir(path: Path) {
        path.deleteRecursively()
        path.deleteIfExists()
    }

    /**
     * 获取 pcap 文件存储文件夹
     * */
    fun getPCAPDir(): Path {
        val pcapsDir = OUTPUT.resolve("pcaps")
        pcapsDir.createDirectories()
        return pcapsDir
    }

    /**
     * 获取某个 pcap 文件的具体路径
     * */
    fun getPCAPFile(fileName: String): Path {
        return getPCAPDir().resolve("$fileName.pcap")
    }

    /**
     * 获取截图所在路径
     * */
    fun getScreencapDir(packageName: String): Path {
        val screencapDir = OUTPUT.resolve("screencaps").resolve(packageName)
        screencapDir.createDirectories()
        return screencapDir
    }

    /**
     * 获取一个临时文件
     * */
    fun getTempFile(): Path {
        return OUTPUT.resolve("tmp").resolve("log.txt")
    }

    /**
     * 将 step-21--g0a4-1719933587519.png 这样的文件名按照 step 次序排列
     * @param dirPath 存储截图文件的文件夹
     * */
    fun xmlsInSequence(dirPath: Path): List<Path> {
        val fileList = dirPath.listDirectoryEntries()
            .filter { it.extension == "xml" }
            .sortedWith(compareBy {
                extractNumber(it.fileName.toString())
            }).toList()
        return fileList
    }

    /**
     * e.g. 从 step-21--g0a4-1719933587519.png 中提取出 21
     * */
    internal fun extractNumber(str: String): Int {
        val find = RegexUtils.numberInFileName.find(str)
        val ret = find?.value ?: Int.MAX_VALUE.toString()
        return ret.toInt()
    }
}
